package automatique;

import java.net.URI;
import java.util.*;
import jwnl.JWNLDistances;
import org.semanticweb.owl.apibinding.OWLManager;
import org.semanticweb.owl.model.OWLOntology;
import org.semanticweb.owl.model.OWLOntologyCreationException;
import org.semanticweb.owl.model.OWLOntologyManager;

// Classification Automatique par Agregation
public class Classification {

    JWNLDistances jwnl;
    ArrayList<Element> Ens; // ensemble initial des éléments é classer
    ArrayList<Ensemble> EC; // ensemble des classes ou regroupements
    double seuille_class; // distance inférieure é 20 pour laquelle, les classes seront regroupées ou fusionnées

    Classification() {
        Ens = new ArrayList<Element>();
        EC = new ArrayList<Ensemble>();
        jwnl = new JWNLDistances();
        jwnl.Initialize();
        seuille_class = 20;
    }

    double determination_seuille_class() // selon la moyenne des distances entre les éléments
    { // 1/3 moyenne des distances
        double d = 0;
        for (int i = 0; i < Ens.size(); i++) {
            for (int j = 0; j < Ens.size(); j++) {
                d += Ens.get(i).distance(Ens.get(j), jwnl);
            }
        }
        d = d / (Ens.size() * Ens.size());
        seuille_class = d;
        return (seuille_class);
    }

// ______________ pour test : remplissage de valeur aléatoire des élements é classer
    void Remplir_Ens_Onto(String physicalURI) {
        OWLOntologyManager manager = null;
        OWLOntology ontology = null;
        Element e = null;
        int i = 0;
        try {

            manager = OWLManager.createOWLOntologyManager();
            URI physicalURI1 = URI.create(physicalURI);
            ontology = manager.loadOntologyFromPhysicalURI(physicalURI1);
            Object[] ont = ontology.getReferencedClasses().toArray();
            for (i = 0; i < ont.length; i++) {
                e = new Element(Integer.toString(i), ont[i].toString());
                System.out.println("==tmp :" + ont[i].toString());
                Ens.add(e);
            }

        } catch (OWLOntologyCreationException ex) {
            System.out.println("The ontology could not be created: " + ex.getMessage());
        }
    }

    // Affichage de l'ensemble initial des éléments é classer
    void Afficher_Ens() {
        System.out.println("______________________ Les elements de l'ensemble__________");
        for (int i = 0; i < Ens.size(); i++) {
            System.out.println(Ens.get(i).Libelet + " " + Ens.get(i).Value);
        }
        System.out.println("________________");
    }


// ---- affichage des classes ou groupes et leurs élément aprés classification
    void Afficher_Classes() {
        System.out.println(" Nombre classes=" + EC.size());
        System.out.println("_____________________________________________");
        for (int i = 0; i < EC.size(); i++) {
            System.out.println("____classe " + i + "   Nbre el=" + EC.get(i).Ens.size() + "    -------");
            System.out.println("Valeur centre: " + EC.get(i).Centre.Value);
            System.out.println("____Element______");
            System.out.println("_ Eléments Libelet : ");
            for (int j = 0; j < EC.get(i).Ens.size(); j++) {
                System.out.println(EC.get(i).Ens.get(j).Libelet + " ");
            }
            System.out.println("_ Eléments Valeur : ");
            for (int j = 0; j < EC.get(i).Ens.size(); j++) {
                System.out.println(EC.get(i).Ens.get(j).Value + " ");
            }

        }
        System.out.println("_____________________________________________");


    }

// intilisation des classes avec chaque élément est une classe
    void class_initiales() {
        for (int i = 0; i < Ens.size(); i++) {
            EC.add(new Ensemble(Ens.get(i)));
        }
    }


    // traitement de classification
    void traitement_classification() {
        boolean change;
        class_initiales();

        do {
            change = false;
            for (int i = 0; i < EC.size(); i++) {
                for (int j = 0; j < EC.size() && i < EC.size(); j++) {
                    if (i != j) {
                        if (EC.get(i).distance(EC.get(j), jwnl) < this.seuille_class) {
                            EC.get(i).fusion_ensembles(EC.get(j), jwnl);
                            EC.remove(j);
                            change = true;
                        }
                    }
                }
            }

        } while (change);
    }

    public static void main(String[] args) {
        Classification C = new Classification();

        C.Remplir_Ens_Onto("file:/C:/Users/mida/Desktop/Example/Wildlife.owl");

        C.Afficher_Ens();

        double S = C.determination_seuille_class();
        System.out.println("seuille= " + S);

        System.out.println("_______debut classification ___");
        C.traitement_classification();
        System.out.println("________Fin classification _____");

        C.Afficher_Classes();
    }
}
